/**
*  \file contactor.c
*
*  \brief Contactor Control
*
*  \author yingqin.wu <yingqin.wu@linde-china.com>
*
*/

/*===============================================[ private includes  ]================================================*/
#include "contactor.h"
#include "../assertor/assertor.h"
#include "../pal/pal_mem.h"
#include "../cdt/cdt.h"
/*===============================================[ private defines   ]================================================*/

/*===============================================[ private datatypes ]================================================*/

/*===============================================[ private variables ]================================================*/

/*===============================================[ private functions ]================================================*/

/*===============================================[ inline functions  ]================================================*/

/*===============================================[ public functions  ]================================================*/

RC contactor_construct(
   struct contactor_obj *me,
   struct interpol_u16_u16_obj const *pwm_tighten,
   struct interpol_u16_u16_obj const * pwm_hold,
   U16 on_ticks )
{
   ASSERTOR_PRE( NIL != me,"NIL is not allowed as object pointer." );
   ASSERTOR_PRE( NIL != pwm_tighten,"pwm_tighten is not allowed to be NIL." );
   ASSERTOR_PRE( NIL != pwm_hold,"pwm_hold is not allowed to be NIL." );

   pal_memzero( me, sizeof me );
   me->tighten_table=pwm_tighten;
   me->hold_table=pwm_hold;
   me->on_ticks= on_ticks;
   me->current_state = contactor_state_release;

   return RC_SUCCESS;
}


U16 contactor_service( struct contactor_obj *me, U16 supply_voltage, BO contactor )
{
   U16 rv=0;
   ASSERTOR_PRE( NIL != me,"NIL is not allowed as object pointer." );

   switch ( me->current_state )
   {
      case contactor_state_release:
      {
         if( contactor )
         {
            me->tighten_counter=me->on_ticks;  /* reload the counter */
            me->current_state=contactor_state_tighten;
            rv=interpol_u16_u16( me->tighten_table, supply_voltage );
         }
         else
         {
            rv=0;
         }
         break;
      }
      case contactor_state_tighten:
      {
         if( contactor )
         {
               if(CDT(&me->tighten_counter))
               {
                  rv=interpol_u16_u16( me->hold_table, supply_voltage );
                  me->current_state=contactor_state_hold;
               }
               else
               {
                  rv=interpol_u16_u16( me->tighten_table, supply_voltage );
               }

               if(rv==0)
               {
                  me->current_state=contactor_state_error; /* T4 */
               }
         }
         else
         {
            me->current_state=contactor_state_release;
         }
         break;
      }
      case contactor_state_hold:
      {
         if( contactor )
         {
            rv=interpol_u16_u16( me->hold_table, supply_voltage );
            if(rv==0)
            {
               me->current_state=contactor_state_error; /* T7 */
            }
         }
         else
         {
            me->current_state=contactor_state_release; /* T5 */
         }
         break;
      }
      case contactor_state_error:
      {
         rv=0;
         if( me->reset_error )
         {
            me->reset_error=FALSE;
            me->current_state=contactor_state_release; /* T8 */
         }
         break;
      }
      default:
      {
         ASSERTOR_ILLEGAL_DEFAULT("invalid state");
         break;
      }

   }

   return rv;
}

void contactor_clear_error(struct contactor_obj *me )
{
   ASSERTOR_PRE( NIL != me,"NIL is not allowed as object pointer." );
   me->reset_error=TRUE;
}

BO contactor_get_status(struct contactor_obj const*me , enum contactor_state *state)
{
   ASSERTOR_PRE( NIL != me,"NIL is not allowed as object pointer." );
   if( NIL != state )
   {
      *state=me->current_state;
   }
   return (me->current_state==contactor_state_hold) || (me->current_state==contactor_state_tighten) ;
}

/*===============================================[ private functions ]================================================*/

/***********************************************************************************************************************
*                             Copyright 2018 Linde Material Handling. All rights reserved.                             *
***********************************************************************************************************************/
